//多个进程同时读写同一个资源出现的数据异常
#include "Mutex.hpp"
#include <iostream>
using namespace std;
#include <pthread.h>
#include <unistd.h>
#include <vector>
#define NUM 3
int tickets=1000;
pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;//全局创建条件变量不需要初始化跟销毁，用来解决线程

string toHex(pthread_t tid)
{
    char buffer[128]={0};
    snprintf(buffer,sizeof(buffer),"0x%x",tid);
    return buffer;
}
class threadData//线程数据
{
    public:
    threadData(int n/*,pthread_mutex_t* mutex*/)
    {
        threadname_="threadname-"+to_string(n);
    //mutex_=mutex;
    }
    public:
    string threadname_;
    //pthread_mutex_t* mutex_;
};
// void* getTicket(void*args)
// {
//     threadData*tda=static_cast<threadData*>(args);
//     while(true)
//     {
//         //抢票
//         //访问共享数据前上锁
//         pthread_mutex_lock(&lock/*tda->mutex_*/);
//         if(tickets>0)
//        { 
//        usleep(1000);//为什么放在这里数据会异常？

//         printf("thread is running ,name is: %s   ticketonly:%d\n",tda->threadname_.c_str(),tickets);
//       // usleep(1000);//为什么放在这里就正常
        
//         tickets--;
//         //出来前必须解锁
//         pthread_mutex_unlock(&lock/*tda->mutex_*/);
//        }
//        else
//        {
//         pthread_mutex_unlock(&lock/*tda->mutex_*/);
//        break;
//        }
//     }
//     cout<<"thread quit !! tid is : "<<toHex(pthread_self())<<endl;
//     return nullptr;
// }

void* getTicket(void*args)
{
    threadData*tda=static_cast<threadData*>(args);
    while(true)
    {
        lockguard lockguard1(&lock);//走到这一步已经初始化并创建好锁并且已经加了锁
      pthread_cond_wait(&cond,&lock);//条件变量，解锁并让他进入等待队列，等待唤醒

        cout<<"被唤醒"<<endl;
        if(tickets>0)
       { 
       usleep(1000);//为什么放在这里数据会异常？

        printf("thread is running ,name is: %s   ticketonly:%d\n",tda->threadname_.c_str(),tickets);
      // usleep(1000);//为什么放在这里就正
        
        tickets--;
       // usleep(1000);//抢到票之后做其他事情
       }
       else
       break;
    }
    cout<<"thread quit !! tid is : "<<toHex(pthread_self())<<endl;
    return nullptr;
}
int main()
{
    //局部定义锁
    //pthread_mutex_t mutex;
    //pthread_mutex_init(&mutex,nullptr);//局部锁需要初始化
    vector<pthread_t> tids;
    vector<threadData*>threaddatas;
    for(int i=1;i<=NUM;i++)
{
    //批量创建线程
    pthread_t tid;
    threadData* tda=new threadData(i/*&mutex*/);
    pthread_create(&tid,nullptr,getTicket,tda);
    threaddatas.push_back(tda);
    tids.push_back(tid);

}
//唤醒条件变量里的等待队列
while(1)
{
pthread_cond_broadcast(&cond);//唤醒单个队列，默认唤醒第一个排队的
cout<<"signal success!!"<<endl;
sleep(1);

}
for(int i=0;i<NUM;i++)
{
    pthread_join(tids[i],nullptr);//等待线程
}
for(auto e:threaddatas)
{
    delete e;
}
//局部锁需要释放
 //   pthread_mutex_destroy(&mutex);
    return 0;
}